package cn.yj.core.business.service;

import cn.yj.annotation.pagehelper.page.Page;
import cn.yj.cgs.dba.entity.IntegralGoods;
import cn.yj.cgs.dba.entity.UserIntegralGoods;
import cn.yj.cgs.dba.entity.vo.ExpressProgress;
import cn.yj.cgs.dba.mapper.UserIntegralGoodsMapper;
import cn.yj.common.Enums;
import cn.yj.commons.utils.StringUtils;
import cn.yj.core.business.service.iservice.IIntegralGoodsService;
import cn.yj.core.business.service.iservice.IIntegralService;
import cn.yj.core.business.service.iservice.UserIIntegralGoodsService;
import cn.yj.params.check.annotation.Require;
import cn.yj.tools.exception.ServiceException;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author 永健
 * @since 2021-05-09 13:02
 */
@Service
public class UserIntegralGoodsService extends ServiceImpl<UserIntegralGoodsMapper, UserIntegralGoods> implements UserIIntegralGoodsService {
    private final static Logger log = LoggerFactory.getLogger(UserIntegralGoodsService.class);

    @Resource
    private IIntegralService integralService;

    @Resource
    private IIntegralGoodsService integralGoodsService;

    @Override
    public Page<UserIntegralGoods> pageList(@Require Map<String, Object> prams, @Require Page<UserIntegralGoods> page) {
        baseMapper.findList(prams, page);
        return page;
    }


    @Override
    public ExpressProgress getProgress(@Require String expressNo) {
        UserIntegralGoods userIntegralGoods = baseMapper.selectOne(queryLambda().eq(UserIntegralGoods::getUserGoodsNo
                , expressNo));
        if (StringUtils.isNull(userIntegralGoods)) {
            throw new ServiceException(String.format("找不到该记录:%s", expressNo));
        }
        List<Map<String, Object>> maps = new ArrayList<>(Enums.IntegralGood.PROGRESS.get(userIntegralGoods.getExpressStatus().name()));
        maps.forEach(map -> {
            map.put("isCurrentStatus", false);
            if (userIntegralGoods.getExpressStatus().name().equals(map.get("status").toString())) {
                map.put("isCurrentStatus", true);
            }
        });
        ExpressProgress expressProgress = new ExpressProgress();
        expressProgress.setExpressNo(userIntegralGoods.getExpressNo());
        expressProgress.setCreateTime(userIntegralGoods.getSendTime());
        expressProgress.setProgress(maps);
        expressProgress.setCurrentStatus(userIntegralGoods.getExpressStatus().getMsg());
        return expressProgress;
    }

    @Transactional
    @Override
    public boolean cancel(@Require String userGoodsNo) {
        UserIntegralGoods userIntegralGoods = getByGoodsNoForUpdate(userGoodsNo);
        if (userIntegralGoods.getExpressStatus() == Enums.IntegralGood.EXPRESS_STATUS.DOING) {
            throw new ServiceException("该订单已发货，不可取消");
        }

        // 重复取消判断
        if (userIntegralGoods.getExpressStatus() == Enums.IntegralGood.EXPRESS_STATUS.CANCEL) {
            throw new ServiceException("该订单已取消");
        }

        // 积分回退 库存回退
        if (integralService.updateIntegral(userIntegralGoods.getUserCode(), userIntegralGoods.getAmount(), true,
                Enums.IntegralWater.SOURCE.CANCEL_EXCHANGE, null)) {
            updateExpressStatus(Enums.IntegralGood.EXPRESS_STATUS.CANCEL, userGoodsNo);
            goodsStockCallback(userIntegralGoods.getGoodsNo(),userIntegralGoods.getNum());
        }
        return true;
    }

    private void goodsStockCallback(String goodsNo,int count) {
        // 库存回退
        IntegralGoods integralGoods = integralGoodsService.selectByGoodsNoForUpdate(goodsNo);
        if (StringUtils.isNotNull(integralGoods)) {
            integralGoods.setStock(integralGoods.getStock() + count);
            if (!integralGoodsService.update(integralGoods,
                    new UpdateWrapper<IntegralGoods>().lambda().eq(IntegralGoods::getGoodsNo,
                            integralGoods.getGoodsNo()))) {
                log.error("积分商品记录取消/删除，库存回退更新失败");
                throw new ServiceException("更新失败，请重试...");
            }
        }
    }

    @Transactional
    @Override
    public boolean delete(@Require String userGoodsNo) {
        UserIntegralGoods userIntegralGoods = getByGoodsNoForUpdate(userGoodsNo);
        if (userIntegralGoods.getExpressStatus() != Enums.IntegralGood.EXPRESS_STATUS.DOING) {
            if (userIntegralGoods.getExpressStatus() == Enums.IntegralGood.EXPRESS_STATUS.NO_SEND) {
                // 积分回退 库存回退
                if (integralService.updateIntegral(userIntegralGoods.getUserCode(), userIntegralGoods.getAmount(),
                        true, Enums.IntegralWater.SOURCE.CANCEL_EXCHANGE, null)) {
                    goodsStockCallback(userIntegralGoods.getGoodsNo(),userIntegralGoods.getNum());
                    return baseMapper.delete(updateLambda().eq(UserIntegralGoods::getUserGoodsNo, userGoodsNo)) > Enums.Common.ZERO;
                }
            }
            return baseMapper.delete(updateLambda().eq(UserIntegralGoods::getUserGoodsNo, userGoodsNo)) > Enums.Common.ZERO;
        }
        throw new ServiceException("该订单已发货，不可删除");
    }

    @Transactional
    @Override
    public boolean signFor(@Require String userGoodsNo) {
        UserIntegralGoods userIntegralGoods = getByGoodsNoForUpdate(userGoodsNo);

        if (userIntegralGoods.getExpressStatus() == Enums.IntegralGood.EXPRESS_STATUS.CANCEL) {
            throw new ServiceException("该订单已取消");
        }
        if (userIntegralGoods.getExpressStatus() == Enums.IntegralGood.EXPRESS_STATUS.NO_SEND) {
            throw new ServiceException("该订单未发货");
        }
        if (userIntegralGoods.getExpressStatus() == Enums.IntegralGood.EXPRESS_STATUS.SEND_TO) {
            throw new ServiceException("您已签收过了");
        }
        updateExpressStatus(Enums.IntegralGood.EXPRESS_STATUS.SEND_TO, userGoodsNo);
        return true;
    }


    @Override
    public UserIntegralGoods getByGoodsNoForUpdate(@Require String userGoodsNo) {
        UserIntegralGoods userIntegralGoods = baseMapper.selectByNoForUpdate(userGoodsNo);
        if (StringUtils.isNull(userIntegralGoods)) {
            throw new ServiceException(String.format("找不到该置换记录：%s", userGoodsNo));
        }
        return userIntegralGoods;
    }


    private void updateExpressStatus(Enums.IntegralGood.EXPRESS_STATUS status, String userGoodsNo) {
        UserIntegralGoods userIntegralGoods = new UserIntegralGoods();
        userIntegralGoods.setGoodsNo(userGoodsNo);
        userIntegralGoods.setExpressStatus(status);
        if (!update(userIntegralGoods, updateLambda().eq(UserIntegralGoods::getUserGoodsNo, userGoodsNo))) {
            throw new ServiceException("更新状态失败");
        }
    }

}
